const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const multer = require("multer");
const path = require("path");
const fs = require("fs");

const app = express();
const PORT = process.env.PORT || 3001;
const JWT_SECRET = "your-secret-key-change-in-production";

// 创建上传目录
const uploadDir = path.join(process.cwd(), "uploads");
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, { recursive: true });
}

// 配置 multer
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    // 生成唯一文件名：时间戳 + 随机数 + 原始扩展名
    const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
    const ext = path.extname(file.originalname);
    cb(null, `image-${uniqueSuffix}${ext}`);
  },
});

const upload = multer({
  storage: storage,
  limits: {
    fileSize: 5 * 1024 * 1024, // 5MB 限制
  },
  fileFilter: (req, file, cb) => {
    // 只允许图片文件
    if (file.mimetype.startsWith("image/")) {
      cb(null, true);
    } else {
      cb(new Error("只允许上传图片文件"), false);
    }
  },
});

// 中间件
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 静态文件服务 - 提供上传的图片访问
app.use("/uploads", express.static(uploadDir));

// 模拟数据库
let users = [
  {
    id: "1",
    username: "admin",
    password: "$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi", // password: 123456
    avatarUrl: "https://via.placeholder.com/100x100/007AFF/FFFFFF?text=A",
    createdAt: new Date().toISOString(),
  },
  {
    id: "2",
    username: "testuser",
    password: "$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi", // password: 123456
    avatarUrl: "https://via.placeholder.com/100x100/34C759/FFFFFF?text=T",
    createdAt: new Date().toISOString(),
  },
  {
    id: "3",
    username: "demo",
    password: "$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi", // password: 123456
    avatarUrl: "https://via.placeholder.com/100x100/FF9500/FFFFFF?text=D",
    createdAt: new Date().toISOString(),
  },
];

let posts = [
  {
    id: "1",
    title: "欢迎使用 Green Book",
    content:
      "这是一个基于 React Native 和 Expo 的社交应用，你可以在这里分享你的想法和文章。",
    userId: "1",
    createdAt: new Date(Date.now() - 86400000).toISOString(), // 1天前
    updatedAt: new Date(Date.now() - 86400000).toISOString(),
  },
  {
    id: "2",
    title: "React Native 开发心得",
    content:
      "在开发 React Native 应用时，我发现了一些有用的技巧和最佳实践。首先，合理使用 FlatList 可以显著提升列表性能...",
    userId: "2",
    createdAt: new Date(Date.now() - 172800000).toISOString(), // 2天前
    updatedAt: new Date(Date.now() - 172800000).toISOString(),
  },
  {
    id: "3",
    title: "Expo 开发体验分享",
    content:
      "Expo 为 React Native 开发提供了很多便利，特别是热重载和 OTA 更新功能，大大提升了开发效率。",
    userId: "3",
    createdAt: new Date(Date.now() - 259200000).toISOString(), // 3天前
    updatedAt: new Date(Date.now() - 259200000).toISOString(),
  },
];

// 认证中间件
const authenticateToken = (req, res, next) => {
  const authHeader = req.headers["authorization"];
  const token = authHeader && authHeader.split(" ")[1];

  if (!token) {
    return res.status(401).json({ success: false, message: "访问令牌缺失" });
  }

  jwt.verify(token, JWT_SECRET, (err, user) => {
    if (err) {
      return res.status(403).json({ success: false, message: "访问令牌无效" });
    }
    req.user = user;
    next();
  });
};

// 工具函数
const generateId = () => Math.random().toString(36).substr(2, 9);
const hashPassword = async (password) => await bcrypt.hash(password, 10);
const comparePassword = async (password, hash) =>
  await bcrypt.compare(password, hash);

// 响应格式化
const sendResponse = (res, success, message, data = null, status = 200) => {
  res.status(status).json({
    success,
    message,
    ...(data && { data }),
  });
};

// 路由

// 健康检查
app.get("/api/health", (req, res) => {
  sendResponse(res, true, "服务器运行正常", {
    timestamp: new Date().toISOString(),
  });
});

// 用户注册
app.post("/api/auth/register", async (req, res) => {
  try {
    const { username, password, confirmPassword } = req.body;

    // 验证输入
    if (!username || !password || !confirmPassword) {
      return sendResponse(res, false, "所有字段都不能为空", null, 400);
    }

    if (password !== confirmPassword) {
      return sendResponse(res, false, "两次输入的密码不一致", null, 400);
    }

    if (password.length < 6) {
      return sendResponse(res, false, "密码长度不能少于6位", null, 400);
    }

    // 检查用户名是否已存在
    const existingUser = users.find((u) => u.username === username);
    if (existingUser) {
      return sendResponse(res, false, "用户名已存在", null, 400);
    }

    // 创建新用户
    const hashedPassword = await hashPassword(password);
    const newUser = {
      id: generateId(),
      username,
      password: hashedPassword,
      avatarUrl: `https://via.placeholder.com/100x100/FF3B30/FFFFFF?text=${username
        .charAt(0)
        .toUpperCase()}`,
      createdAt: new Date().toISOString(),
    };

    users.push(newUser);

    // 生成 JWT token
    const token = jwt.sign(
      { userId: newUser.id, username: newUser.username },
      JWT_SECRET,
      { expiresIn: "24h" }
    );

    // 返回用户信息（不包含密码）
    const { password: _, ...userWithoutPassword } = newUser;
    sendResponse(res, true, "注册成功", { user: userWithoutPassword, token });
  } catch (error) {
    console.error("注册错误:", error);
    sendResponse(res, false, "注册失败，请稍后重试", null, 500);
  }
});

// 用户登录
app.post("/api/auth/login", async (req, res) => {
  try {
    const { username, password } = req.body;

    if (!username || !password) {
      return sendResponse(res, false, "用户名和密码不能为空", null, 400);
    }

    // 查找用户
    const user = users.find((u) => u.username === username);
    if (!user) {
      return sendResponse(res, false, "用户不存在", null, 401);
    }

    // 验证密码
    const isValidPassword = await comparePassword(password, user.password);
    if (!isValidPassword) {
      return sendResponse(res, false, "密码错误", null, 401);
    }

    // 生成 JWT token
    const token = jwt.sign(
      { userId: user.id, username: user.username },
      JWT_SECRET,
      { expiresIn: "24h" }
    );

    // 返回用户信息（不包含密码）
    const { password: _, ...userWithoutPassword } = user;
    sendResponse(res, true, "登录成功", { user: userWithoutPassword, token });
  } catch (error) {
    console.error("登录错误:", error);
    sendResponse(res, false, "登录失败，请稍后重试", null, 500);
  }
});

// 获取当前用户信息
app.get("/api/auth/me", authenticateToken, (req, res) => {
  try {
    const user = users.find((u) => u.id === req.user.userId);
    if (!user) {
      return sendResponse(res, false, "用户不存在", null, 404);
    }

    const { password: _, ...userWithoutPassword } = user;
    sendResponse(res, true, "获取用户信息成功", { user: userWithoutPassword });
  } catch (error) {
    console.error("获取用户信息错误:", error);
    sendResponse(res, false, "获取用户信息失败", null, 500);
  }
});

// 根据用户ID获取用户信息
app.get("/api/users/:id", (req, res) => {
  try {
    const { id } = req.params;
    const user = users.find((u) => u.id === id);

    if (!user) {
      return sendResponse(res, false, "用户不存在", null, 404);
    }

    const { password: _, ...userWithoutPassword } = user;
    sendResponse(res, true, "获取用户信息成功", { user: userWithoutPassword });
  } catch (error) {
    console.error("获取用户信息错误:", error);
    sendResponse(res, false, "获取用户信息失败", null, 500);
  }
});

// 图片上传相关路由

// 上传图片
app.post(
  "/api/upload/image",
  authenticateToken,
  upload.single("image"),
  (req, res) => {
    try {
      if (!req.file) {
        return sendResponse(res, false, "请选择要上传的图片", null, 400);
      }

      // 生成图片访问URL
      const imageUrl = `${req.protocol}://${req.get("host")}/uploads/${
        req.file.filename
      }`;

      sendResponse(res, true, "图片上传成功", {
        imageUrl: imageUrl,
        filename: req.file.filename,
        originalName: req.file.originalname,
        size: req.file.size,
        mimetype: req.file.mimetype,
      });
    } catch (error) {
      console.error("图片上传错误:", error);
      sendResponse(res, false, "图片上传失败", null, 500);
    }
  }
);

// 删除图片
app.delete("/api/upload/image/:filename", authenticateToken, (req, res) => {
  try {
    const { filename } = req.params;
    const filePath = path.join(uploadDir, filename);

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      return sendResponse(res, false, "图片不存在", null, 404);
    }

    // 删除文件
    fs.unlinkSync(filePath);

    sendResponse(res, true, "图片删除成功");
  } catch (error) {
    console.error("图片删除错误:", error);
    sendResponse(res, false, "图片删除失败", null, 500);
  }
});

// 文章相关路由

// 获取所有文章
app.get("/api/posts", (req, res) => {
  try {
    const { page = 1, limit = 10, userId } = req.query;
    const pageNum = parseInt(page);
    const limitNum = parseInt(limit);

    let filteredPosts = [...posts];

    // 如果指定了用户ID，只返回该用户的文章
    if (userId) {
      filteredPosts = posts.filter((post) => post.userId === userId);
    }

    // 按创建时间倒序排列
    filteredPosts.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));

    // 分页
    const startIndex = (pageNum - 1) * limitNum;
    const endIndex = startIndex + limitNum;
    const paginatedPosts = filteredPosts.slice(startIndex, endIndex);

    // 为每篇文章添加作者信息
    const postsWithAuthor = paginatedPosts.map((post) => {
      const author = users.find((user) => user.id === post.userId);
      return {
        ...post,
        author: author
          ? {
              id: author.id,
              username: author.username,
              avatarUrl: author.avatarUrl,
            }
          : null,
      };
    });

    sendResponse(res, true, "获取文章列表成功", {
      posts: postsWithAuthor,
      pagination: {
        page: pageNum,
        limit: limitNum,
        total: filteredPosts.length,
        totalPages: Math.ceil(filteredPosts.length / limitNum),
      },
    });
  } catch (error) {
    console.error("获取文章列表错误:", error);
    sendResponse(res, false, "获取文章列表失败", null, 500);
  }
});

// 根据ID获取单篇文章
app.get("/api/posts/:id", (req, res) => {
  try {
    const { id } = req.params;
    const post = posts.find((p) => p.id === id);

    if (!post) {
      return sendResponse(res, false, "文章不存在", null, 404);
    }

    // 添加作者信息
    const author = users.find((user) => user.id === post.userId);
    const postWithAuthor = {
      ...post,
      author: author
        ? {
            id: author.id,
            username: author.username,
            avatarUrl: author.avatarUrl,
          }
        : null,
    };

    sendResponse(res, true, "获取文章成功", { post: postWithAuthor });
  } catch (error) {
    console.error("获取文章错误:", error);
    sendResponse(res, false, "获取文章失败", null, 500);
  }
});

// 创建文章
app.post("/api/posts", authenticateToken, (req, res) => {
  try {
    const { title, content } = req.body;

    // 验证输入
    if (!title || !content) {
      return sendResponse(res, false, "标题和内容不能为空", null, 400);
    }

    if (title.length < 1 || title.length > 100) {
      return sendResponse(res, false, "标题长度应在1-100个字符之间", null, 400);
    }

    if (content.length < 1 || content.length > 5000) {
      return sendResponse(
        res,
        false,
        "内容长度应在1-5000个字符之间",
        null,
        400
      );
    }

    // 创建新文章
    const newPost = {
      id: generateId(),
      title: title.trim(),
      content: content.trim(),
      userId: req.user.userId,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };

    posts.unshift(newPost); // 添加到数组开头

    // 添加作者信息
    const author = users.find((user) => user.id === newPost.userId);
    const postWithAuthor = {
      ...newPost,
      author: author
        ? {
            id: author.id,
            username: author.username,
            avatarUrl: author.avatarUrl,
          }
        : null,
    };

    sendResponse(res, true, "创建文章成功", { post: postWithAuthor }, 201);
  } catch (error) {
    console.error("创建文章错误:", error);
    sendResponse(res, false, "创建文章失败", null, 500);
  }
});

// 更新文章
app.put("/api/posts/:id", authenticateToken, (req, res) => {
  try {
    const { id } = req.params;
    const { title, content } = req.body;

    const postIndex = posts.findIndex((p) => p.id === id);
    if (postIndex === -1) {
      return sendResponse(res, false, "文章不存在", null, 404);
    }

    const post = posts[postIndex];

    // 检查是否是文章作者
    if (post.userId !== req.user.userId) {
      return sendResponse(res, false, "无权限修改此文章", null, 403);
    }

    // 验证输入
    if (!title || !content) {
      return sendResponse(res, false, "标题和内容不能为空", null, 400);
    }

    if (title.length < 1 || title.length > 100) {
      return sendResponse(res, false, "标题长度应在1-100个字符之间", null, 400);
    }

    if (content.length < 1 || content.length > 5000) {
      return sendResponse(
        res,
        false,
        "内容长度应在1-5000个字符之间",
        null,
        400
      );
    }

    // 更新文章
    posts[postIndex] = {
      ...post,
      title: title.trim(),
      content: content.trim(),
      updatedAt: new Date().toISOString(),
    };

    // 添加作者信息
    const author = users.find((user) => user.id === posts[postIndex].userId);
    const postWithAuthor = {
      ...posts[postIndex],
      author: author
        ? {
            id: author.id,
            username: author.username,
            avatarUrl: author.avatarUrl,
          }
        : null,
    };

    sendResponse(res, true, "更新文章成功", { post: postWithAuthor });
  } catch (error) {
    console.error("更新文章错误:", error);
    sendResponse(res, false, "更新文章失败", null, 500);
  }
});

// 删除文章
app.delete("/api/posts/:id", authenticateToken, (req, res) => {
  try {
    const { id } = req.params;

    const postIndex = posts.findIndex((p) => p.id === id);
    if (postIndex === -1) {
      return sendResponse(res, false, "文章不存在", null, 404);
    }

    const post = posts[postIndex];

    // 检查是否是文章作者
    if (post.userId !== req.user.userId) {
      return sendResponse(res, false, "无权限删除此文章", null, 403);
    }

    // 删除文章
    posts.splice(postIndex, 1);

    sendResponse(res, true, "删除文章成功");
  } catch (error) {
    console.error("删除文章错误:", error);
    sendResponse(res, false, "删除文章失败", null, 500);
  }
});

// 搜索文章
app.get("/api/posts/search", (req, res) => {
  try {
    const { q, page = 1, limit = 10 } = req.query;

    if (!q || q.trim().length === 0) {
      return sendResponse(res, false, "搜索关键词不能为空", null, 400);
    }

    const pageNum = parseInt(page);
    const limitNum = parseInt(limit);
    const searchTerm = q.trim().toLowerCase();

    // 搜索文章标题和内容
    const filteredPosts = posts.filter(
      (post) =>
        post.title.toLowerCase().includes(searchTerm) ||
        post.content.toLowerCase().includes(searchTerm)
    );

    // 按创建时间倒序排列
    filteredPosts.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));

    // 分页
    const startIndex = (pageNum - 1) * limitNum;
    const endIndex = startIndex + limitNum;
    const paginatedPosts = filteredPosts.slice(startIndex, endIndex);

    // 为每篇文章添加作者信息
    const postsWithAuthor = paginatedPosts.map((post) => {
      const author = users.find((user) => user.id === post.userId);
      return {
        ...post,
        author: author
          ? {
              id: author.id,
              username: author.username,
              avatarUrl: author.avatarUrl,
            }
          : null,
      };
    });

    sendResponse(res, true, "搜索文章成功", {
      posts: postsWithAuthor,
      pagination: {
        page: pageNum,
        limit: limitNum,
        total: filteredPosts.length,
        totalPages: Math.ceil(filteredPosts.length / limitNum),
      },
      searchTerm: q,
    });
  } catch (error) {
    console.error("搜索文章错误:", error);
    sendResponse(res, false, "搜索文章失败", null, 500);
  }
});

// multer 错误处理中间件
app.use((err, req, res, next) => {
  if (err instanceof multer.MulterError) {
    if (err.code === "LIMIT_FILE_SIZE") {
      return sendResponse(
        res,
        false,
        "图片文件过大，请选择小于5MB的图片",
        null,
        400
      );
    }
    return sendResponse(res, false, "文件上传错误: " + err.message, null, 400);
  } else if (err) {
    if (err.message === "只允许上传图片文件") {
      return sendResponse(res, false, "只允许上传图片文件", null, 400);
    }
    console.error("服务器错误:", err);
    return sendResponse(res, false, "服务器内部错误", null, 500);
  }
  next();
});

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error("服务器错误:", err);
  sendResponse(res, false, "服务器内部错误", null, 500);
});

// 404 处理
app.use("*", (req, res) => {
  sendResponse(res, false, "接口不存在", null, 404);
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`🚀 Mock 服务器运行在 http://localhost:${PORT}`);
  console.log(`📚 API 文档:`);
  console.log(`\n🔐 认证相关:`);
  console.log(`   GET  /api/health - 健康检查`);
  console.log(`   POST /api/auth/register - 用户注册`);
  console.log(`   POST /api/auth/login - 用户登录`);
  console.log(`   GET  /api/auth/me - 获取当前用户信息`);
  console.log(`   GET  /api/users/:id - 根据ID获取用户信息`);
  console.log(`\n📝 文章相关:`);
  console.log(`   GET    /api/posts - 获取文章列表 (支持分页和用户筛选)`);
  console.log(`   GET    /api/posts/:id - 根据ID获取单篇文章`);
  console.log(`   POST   /api/posts - 创建文章 (需要认证)`);
  console.log(`   PUT    /api/posts/:id - 更新文章 (需要认证)`);
  console.log(`   DELETE /api/posts/:id - 删除文章 (需要认证)`);
  console.log(`   GET    /api/posts/search - 搜索文章 (支持分页)`);
  console.log(`\n🖼️ 图片上传:`);
  console.log(`   POST   /api/upload/image - 上传图片 (需要认证)`);
  console.log(`   DELETE /api/upload/image/:filename - 删除图片 (需要认证)`);
  console.log(`   GET    /uploads/:filename - 访问上传的图片`);
  console.log(`\n📋 查询参数说明:`);
  console.log(`   - page: 页码 (默认: 1)`);
  console.log(`   - limit: 每页数量 (默认: 10)`);
  console.log(`   - userId: 用户ID (仅文章列表)`);
  console.log(`   - q: 搜索关键词 (仅搜索接口)`);
});

module.exports = app;
